#include "threadPool.h"

ThreadPool::ThreadPool(int min, int max) : m_maxThread(max), m_minThread(min),
                                           m_stop(false), m_idleThread(min), m_curThread(min)
{
    // 创建管理者线程
    m_manager = new thread(&ThreadPool::manager, this);
    // 创建工作线程
    for (int i = 0; i < min; i++)
    {
        thread t(&ThreadPool::worker, this);
        m_workers.insert(make_pair(t.get_id(), move(t)));
    }
}

void ThreadPool::manager(void)
{
    while (!m_stop.load())
    {
        this_thread::sleep_for(chrono::seconds(1));
        int idel = m_idleThread.load();
        int cur = m_curThread.load();
        // 线程删除
        if (idel > cur / 2 && cur > m_minThread)
        {
            m_exitThread.store(2);
            m_condition.notify_all();
            lock_guard<mutex> lck(m_idsMutex);
            for (auto id : m_ids)
            {
                auto it = m_workers.find(id);
                if (it != m_workers.end())
                {
                    cout << "---线程 " << (*it).first << "被删除了" << endl;
                    (*it).second.join();
                    m_workers.erase(it);
                }
            }
            m_ids.clear();
        }
        else if (idel == 0 && cur < m_maxThread) // 线程添加
        {
            thread t(&ThreadPool::worker, this);
            m_workers.insert(make_pair(t.get_id(), move(t)));
            m_curThread++;
            m_idleThread++;
        }
    }
}

void ThreadPool::worker(void)
{
    while (!m_stop.load())
    {
        function<void(void)> task = nullptr;
        {
            unique_lock<mutex> locker(m_queueMutex);
            if (m_tasks.empty() && !m_stop)
            {
                m_condition.wait(locker);
                if (m_exitThread.load() > 0)
                {
                    m_curThread--;
                    m_idleThread--;
                    m_exitThread--;
                    cout << "===线程退出 , id " << this_thread::get_id() << endl;
                    lock_guard<mutex> lck(m_idsMutex);
                    m_ids.emplace_back(this_thread::get_id());
                    return;
                }
            }
            if (!m_tasks.empty())
            {
                cout << "取出一个任务 " << endl;
                task = move(m_tasks.front());
                m_tasks.pop();
            }
        }
        if (task)
        {
            m_idleThread--;
            task();
            m_idleThread++;
        }
    }
}

void ThreadPool::addTask(function<void(void)> task)
{
    {
        lock_guard<mutex> locker(m_queueMutex);
        m_tasks.emplace(task);
    }
    m_condition.notify_one();
}

ThreadPool::~ThreadPool()
{
    m_stop = true;
    m_condition.notify_all();
    for (auto &it : m_workers)
    {
        thread &t = it.second;
        if (t.joinable())
        {
            cout << "***线程 " << t.get_id() << "将要退出了" << endl;
            t.join();
        }
    }
    if (m_manager->joinable())
    {
        m_manager->join();
    }
}
